package cn.edu.cug.cs.gtl.docsrv.shp.manager;

import cn.edu.cug.cs.gtl.common.Pair;
import cn.edu.cug.cs.gtl.docsrv.doc.DocManager;
import cn.edu.cug.cs.gtl.docsrv.shp.querier.BlockQuerier;
import cn.edu.cug.cs.gtl.docsrv.shp.querier.DefaultBlockQuerier;
import cn.edu.cug.cs.gtl.docsrv.shp.updater.BlockUpdater;
import cn.edu.cug.cs.gtl.docsrv.shp.updater.DefaultBlockUpdater;
import cn.edu.cug.cs.gtl.io.FileDataSplitter;
import cn.edu.cug.cs.gtl.mybatis.Session;
import cn.edu.cug.cs.gtl.mybatis.mapper.shp.ShpAll;

import cn.edu.cug.cs.gtl.mybatis.mapper.shp.ShpFile;
import cn.edu.cug.cs.gtl.mybatis.mapper.shp.ShpItem;
import cn.edu.cug.cs.gtl.mybatis.mapper.shp.ShpItemMapper;
import cn.edu.cug.cs.gtl.protos.TimeValue;
import org.locationtech.jts.geom.Envelope;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 基于关系数据库Oracle Spatial实现的图形数据管理器
 * 数据的入库采用ArcGIS/QGIS/MapBuilder等工具入库
 * 借助GeoTools中的Oracle插件实现查询
 */
public class SDBShpManager extends ShpManager{

    /**
     * 构造函数
     *
     * @param session
     */
    public SDBShpManager(Session session) {
        super(session);
    }

    /**
     * 将一个由shpItem+shpFile组成的图形文档插入数据库
     *
     * @param shpItem 图形元数据信息
     * @param shpFile 图形文件内容
     * @return
     */
    @Override
    public boolean insert(ShpItem shpItem, ShpFile shpFile) {
        return false;
    }

    /**
     * 将一个由ShpAll组成的图形文档插入数据库
     *
     * @param shpAll 图形文档
     * @return 成功返回true, 否则返回false
     */
    @Override
    public boolean insert(ShpAll shpAll) {
        return false;
    }

    /**
     * 读取本地目录中的所有图形文档，将其插入图形库中
     *
     * @param localDir 本地目录
     * @return 成功返回true, 否则返回false
     */
    @Override
    public boolean insert(String localDir) {
        return false;
    }

    /**
     * 根据shpInternalId删除数据库中对应的图形文档记录
     *
     * @param shpItem 必须填充shpInternalId
     * @return
     */
    @Override
    public boolean delete(ShpItem shpItem) {
        return false;
    }

    /**
     * 根据shpInternalId删除数据库中对应的图形文档记录
     *
     * @param shpAll 必须填充shpInternalId
     * @return
     */
    @Override
    public boolean delete(ShpAll shpAll) {
        return false;
    }

    /**
     * 根据shpItem+shpFile更新数据库中的图形文档记录
     *
     * @param shpItem 该对象的shpInternalId必须填充
     * @param shpFile 更新文档文件的内容
     * @return 更新成功返回true, 否则返回false
     */
    @Override
    public boolean update(ShpItem shpItem, ShpFile shpFile) {
        return false;
    }

    /**
     * 根据根据shpAll中的信息更新数据库中的记录
     *
     * @param shpAll 该对象的shpInternalId必须填充
     * @return 更新成功返回true, 否则返回false
     */
    @Override
    public boolean update(ShpAll shpAll) {
        return false;
    }


    @Override
    public ShpAll queryByInternalId(BigDecimal shpInternalId) {
        return null;
    }

    @Override
    public List<ShpAll> queryByEnTitle(String shpEnTitle) {
        return null;
    }

    @Override
    public List<ShpAll> queryByComment(String shpCnTitle) {
        return null;
    }

    @Override
    public List<ShpAll> queryByType(String shpType) {
        return null;
    }

    @Override
    public List<ShpAll> queryByAppendDate(TimeValue begin, TimeValue end) {
        return null;
    }


    @Override
    public List<ShpAll> query(Map<String, Object> parameters) {
        return null;
    }


    /**
     * 查询得到所有ShapeBlock的边界矩形
     * @return
     */
    @Override
    public  List<Pair<BigDecimal, Envelope>> queryAllEnvelopes(){
        try {
            ShpItemMapper shpItemMapper = session.getMapper(ShpItemMapper.class);
            List<LinkedHashMap<String, Object>> ls = shpItemMapper.selectAllInternalIdAndExtents();
            System.out.println(ls.size());
            List<Pair<BigDecimal, Envelope>> r = new ArrayList<>();
            for (LinkedHashMap<String, Object> l: ls){
                BigDecimal id = (BigDecimal)l.get("SHP_INTERNAL_ID");
                String coords = (String)l.get("SHP_EXTENT");
                String [] cs = coords.split(FileDataSplitter.COMMA.getDelimiter());
                double minX = Double.valueOf(cs[0]).doubleValue();
                double maxX = Double.valueOf(cs[1]).doubleValue();
                double minY = Double.valueOf(cs[2]).doubleValue();
                double maxY = Double.valueOf(cs[3]).doubleValue();
                Envelope envelope = new Envelope(minX,maxX,minY,maxY);
                r.add(new Pair<>(id,envelope));
            }
            return r;
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取图形块ShapeBlock级别的查询器
     *
     * @return
     */
    @Override
    public BlockQuerier getBlockQuerier() {
        return new DefaultBlockQuerier(this);
    }

    /**
     * 获取图形块ShapeBlock级别的更新器
     * @return
     */
    @Override
    public BlockUpdater getBlockUpdater() {
        return new DefaultBlockUpdater(this);
    }

}
